package org.jsola.hr.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import org.jsola.admin.dto.DictItemUpdateDTO;
import org.jsola.admin.entity.DictItemDO;
import org.jsola.common.DateKit8;
import org.jsola.common.PageKit;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.DateUtils;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.common.ExcelKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IMissionCenterDAO;
import org.jsola.hr.dao.IMissionCenterItemDAO;
import org.jsola.hr.dto.MissionCenterAddDTO;
import org.jsola.hr.dto.MissionCenterExportWrongDTO;
import org.jsola.hr.dto.MissionCenterExtraAddDTO;
import org.jsola.hr.dto.MissionCenterUpdateDTO;
import org.jsola.hr.entity.*;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.hr.query.MissionCenterQuery;
import org.jsola.hr.service.*;
import org.jsola.hr.service.excel.MissionCenterImportListener;
import org.jsola.hr.vo.*;
import org.jsola.user.core.TokenUser;
import org.jsola.user.entity.UserDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

import static org.jsola.hr.constant.HrConstants.FIXED_COMPANY;


/**
 * 任务调度中心任务表
 *
 * @author zhr
 */
@Service("hrMissionCenterServiceImpl")
public class MissionCenterServiceImpl implements IMissionCenterService {

    @Autowired
    private IMissionCenterDAO missionCenterDAO;

    @Autowired
    private IMissionCenterItemService missionCenterItemService;

    @Autowired
    private IMissionCenterItemDAO missionCenterItemDAO;

    @Autowired
    private IUserRoleCompanyService userRoleCompanyService;

    @Autowired
    private IGroupCompanyService groupCompanyService;

    @Autowired
    private IUserProviderService userProviderService;

    @Autowired
    private ICompanyService companyService;

    private static final String NAME_WRONGS = "nameWrongs";

    private static final String ID_CARD_WRONGS = "idCardWrongs";

    private static final String NAME_FLAG = "name";

    private static final String ID_CARD_FLAG = "idCard";

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public MissionCenterVO save(MissionCenterAddDTO missionCenterAddDTO, TokenUser tokenUser) {
        // 转DO
        MissionCenterDO missionCenterDO = missionCenterAddDTO.to(MissionCenterDO.class);
        // 保存
        missionCenterDO = save(missionCenterDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return missionCenterDO.to(MissionCenterVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(MissionCenterUpdateDTO missionCenterUpdateDTO, TokenUser tokenUser) {
        //转DO
        MissionCenterDO missionCenterDO = missionCenterUpdateDTO.to(MissionCenterDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(missionCenterDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... missionCenterIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) missionCenterIds);
    }


    @Override
    public MissionCenterVO selectById(String missionCenterId, String siteId) {
        MissionCenterDO missionCenterDO = selectDOById(missionCenterId, siteId);
        if (missionCenterDO == null) {
            return null;
        }
        return missionCenterDO.to(MissionCenterVO.class);
    }

    @Override
    public List<MissionCenterListVO> select(MissionCenterQuery missionCenterQuery, String siteId) {
        List<MissionCenterDO> missionCenterDOList = selectDO(missionCenterQuery, siteId);
        if (CollectionUtils.isEmpty(missionCenterDOList)) {
            return missionCenterDOList == null ? null : new ArrayList<>();
        }
        return missionCenterDOList.stream()
                .map(missionCenterDO -> missionCenterDO.to(MissionCenterListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(MissionCenterQuery missionCenterQuery, String siteId) {
        Example example = buildExample(missionCenterQuery, siteId);
        return missionCenterDAO.selectCountByExample(example);
    }

    @Override
    public Page<MissionCenterListVO> selectPage(MissionCenterQuery missionCenterQuery, String siteId) {
        Example example = buildExample(missionCenterQuery, siteId);
        example.orderBy("gmtCreate").desc();
        Page<MissionCenterDO> page;
        if (!ObjectUtils.isEmpty(missionCenterQuery.getMissionCenterState())) {
            List<MissionCenterDO> missionCenterList = missionCenterDAO.selectByExample(example);
            List<MissionCenterDO> missionCenterFilter = missionCenterList.stream().filter(missionCenter -> {
                List<MissionCenterItemDO> itemList = missionCenterItemService
                        .selectByMissionCenterId(missionCenter.getId(), siteId);
                if (!CollectionUtils.isEmpty(itemList)) {
                    List<Integer> itemStateList = itemList.stream()
                            .map(MissionCenterItemDO::getState).collect(Collectors.toList());
                    if (1 == missionCenterQuery.getMissionCenterState()) {
                        return !itemStateList.contains(0) && !itemStateList.contains(2);
                    } else {
                        return itemStateList.contains(missionCenterQuery.getMissionCenterState());
                    }
                } else {
                    return false;
                }
            }).collect(Collectors.toList());
            page = PageKit.startPage(missionCenterFilter, missionCenterQuery.getPageNo(), missionCenterQuery.getPageSize());
        } else {
            page = missionCenterDAO.selectPageByExample(example,
                    missionCenterQuery.getPageNo(),
                    missionCenterQuery.getPageSize());
        }
        Page<MissionCenterListVO> resultPage = page.to(MissionCenterListVO.class);
        List<MissionCenterListVO> resultList = resultPage.getEntities();
        resultPage.setEntities(fillNumber(resultList, true, siteId));
        return resultPage;
    }

    @Override
    public MissionCenterDO selectDOById(String missionCenterId, String siteId) {
        return listById(missionCenterId, siteId);
    }

    @Override
    public List<MissionCenterDO> selectDO(MissionCenterQuery missionCenterQuery, String siteId) {
        Example example = buildExample(missionCenterQuery, siteId);
        return missionCenterDAO.selectByExample(example);
    }

    @Override
    public MissionCenterImportVO parseExcel(File file, TokenUser tokenUser) {
        MissionCenterImportVO missionCenterImportVO = new MissionCenterImportVO();
        // 解析Excel
        MissionCenterImportListener missionCenterImportListener = new MissionCenterImportListener();
        missionCenterImportListener.setTokenUser(tokenUser);
        missionCenterImportListener.setParseOnly(true);
        EasyExcel.read(file, missionCenterImportListener).sheet().doRead();
        if (!missionCenterImportListener.getCheckHead()) {
            throw new ParamException("表头不正确,EXCEL前两列必须为姓名,身份证号");
        }
        if (!missionCenterImportListener.getCheckDateSize()) {
            String wrongsIndexStr = String.join(",", missionCenterImportListener.getDateSizeWrongsIndex());
            throw new ParamException("表格数据有误,第 " + wrongsIndexStr + " 行数据大于表头数量");
        }
        if (!CollectionUtils.isEmpty(missionCenterImportListener.getRepeatsHead())) {
            String repeatsHead = String.join(",", missionCenterImportListener.getRepeatsHead());
            throw new ParamException("表头: " + repeatsHead + " 重复");
        }
        // 把导入的表头和数据,数据结构修改一下
        Map<Integer, String> allHeadMap = missionCenterImportListener.getAllHeadMap();
        List<Map<Integer, String>> parseList = missionCenterImportListener.getParseList();
        Map<Integer, Map<String, String>> wrongsDateMap = missionCenterImportListener.getWrongsDateMap();
        List<String> headList = new ArrayList<>();
        List<Map<String, String>> headData = new ArrayList<>();
        parseExcelHead(allHeadMap, parseList, headList, headData, wrongsDateMap);
        missionCenterImportVO.setHead(headList);
        missionCenterImportVO.setHeadDataMap(headData);
        return missionCenterImportVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer saveExcel(MissionCenterExtraAddDTO missionCenterExtraAddDTO, TokenUser tokenUser) {
        String headStr = String.join(",", missionCenterExtraAddDTO.getHead());
        MissionCenterAddDTO missionCenterAddDTO = missionCenterExtraAddDTO.to(MissionCenterAddDTO.class);
        missionCenterAddDTO.setTableHead(headStr);
        missionCenterAddDTO.setFileType(1);
        MissionCenterVO missionCenterVO = save(missionCenterAddDTO, tokenUser);
        List<String> headDataList = missionCenterExtraAddDTO.getHeadDate();
        List<MissionCenterItemDO> insertList = new ArrayList<>();
        for (String headData : headDataList) {
            MissionCenterItemDO missionCenterItemDO = new MissionCenterItemDO();
            missionCenterItemDO.setMissionCenterId(missionCenterVO.getId());
            missionCenterItemDO.setTableData(headData);
            missionCenterItemDO.setState(0);
            missionCenterItemDO.setSiteId(tokenUser.getSiteId());
            missionCenterItemDO.setGmtCreate(new Date());
            missionCenterItemDO.setCreateUserId(tokenUser.getUserId());
            missionCenterItemDO.setGmtModified(new Date());
            missionCenterItemDO.setModifiedUserId(tokenUser.getUserId());
            missionCenterItemDO.setValid(true);
            insertList.add(missionCenterItemDO);
        }
        return missionCenterItemDAO.insertListAndSetId(insertList);
    }

    @Override
    public MissionCenterStatisticsVO selectTopStatistics(MissionCenterQuery missionCenterQuery, TokenUser tokenUser) {
        MissionCenterStatisticsVO missionCenterStatisticsVO = new MissionCenterStatisticsVO();
        Example example = buildExample(missionCenterQuery, tokenUser.getSiteId());
        // 根据条件查询出派单记录
        List<MissionCenterDO> missionCenterList = missionCenterDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(missionCenterList)) {
            return initTopStatistics(missionCenterStatisticsVO);
        }
        // 取出Id
        List<String> missionCenterIdList =
                missionCenterList.stream().map(MissionCenterDO::getId).collect(Collectors.toList());
        List<MissionCenterItemDO> missionCenterItemList = new ArrayList<>();
        // 根据每条记录查询记录中的子项,如果子项中有异常人数,异常派单数+1。同理存在未完成人数,未完成派单数+1。
        // 最终,若异常人数和未完成人数都不存在并且子项不为空则说明派单子项全部完成,完成派单数+1
        int abnormalDispatchCount = 0;
        int completedDispatchCount = 0;
        int unfinishedDispatchCount = 0;
        for (String missionCenterId : missionCenterIdList) {
            List<MissionCenterItemDO> itemList = missionCenterItemService
                    .selectByMissionCenterId(missionCenterId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(itemList)) {
                List<Integer> itemStateList = itemList.stream()
                        .map(MissionCenterItemDO::getState).collect(Collectors.toList());
                if (itemStateList.contains(2)) {
                    abnormalDispatchCount += 1;
                }
                if (itemStateList.contains(0)) {
                    unfinishedDispatchCount += 1;
                }
                if (!itemStateList.contains(2) && !itemStateList.contains(0)) {
                    completedDispatchCount += 1;
                }
                missionCenterItemList.addAll(itemList);
            }
        }
        Map<Integer, Long> groupByState = missionCenterItemList.stream()
                .collect(Collectors.groupingBy(MissionCenterItemDO::getState, Collectors.counting()));
        // 异常派单数
        missionCenterStatisticsVO.setAbnormalDispatchCount(abnormalDispatchCount);
        // 成功派单数
        missionCenterStatisticsVO.setCompletedDispatchCount(completedDispatchCount);
        // 未完成派单数
        missionCenterStatisticsVO.setUnfinishedDispatchCount(unfinishedDispatchCount);
        // 已完成人数
        missionCenterStatisticsVO.setCompletedCount(null == groupByState.get(1) ? 0 : groupByState.get(1).intValue());
        // 异常人数
        missionCenterStatisticsVO.setAbnormalCount(null == groupByState.get(2) ? 0 : groupByState.get(2).intValue());
        // 未完成人数
        missionCenterStatisticsVO.setUnfinishedCount(null == groupByState.get(0) ? 0 : groupByState.get(0).intValue());
        // 总派单人数
        missionCenterStatisticsVO.setDispatchEmpCount(missionCenterItemList.size());
        // 合计派单次数
        missionCenterStatisticsVO.setDispatchCount(missionCenterList.size());
        return missionCenterStatisticsVO;
    }


    @Override
    public MissionCenterStatisticsVO selectReceiveTopStatistics(String missionCenterId, TokenUser tokenUser) {
        MissionCenterStatisticsVO missionCenterStatisticsVO = new MissionCenterStatisticsVO();
        List<MissionCenterItemDO> missionCenterItemList =
                missionCenterItemService.selectByMissionCenterId(missionCenterId, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(missionCenterItemList)) {
            return initTopStatistics(missionCenterStatisticsVO);
        }
        Map<Integer, Long> groupByState = missionCenterItemList.stream()
                .collect(Collectors.groupingBy(MissionCenterItemDO::getState, Collectors.counting()));
        // 总接单人数
        missionCenterStatisticsVO.setDispatchEmpCount(missionCenterItemList.size());
        // 异常人数
        missionCenterStatisticsVO.setAbnormalCount(null == groupByState.get(2) ? 0 : groupByState.get(2).intValue());
        // 已完成人数
        missionCenterStatisticsVO.setCompletedCount(null == groupByState.get(1) ? 0 : groupByState.get(1).intValue());
        // 未完成人数
        missionCenterStatisticsVO.setUnfinishedCount(null == groupByState.get(0) ? 0 : groupByState.get(0).intValue());
        return missionCenterStatisticsVO;
    }

    @Override
    public MissionCenterStatisticsVO selectAllReceiveTopStatistics(MissionCenterQuery missionCenterQuery, TokenUser tokenUser) {
        MissionCenterStatisticsVO missionCenterStatisticsVO = new MissionCenterStatisticsVO();
        List<MissionCenterListVO> resultList = viewMissionList(missionCenterQuery, tokenUser);
        if (CollectionUtils.isEmpty(resultList)) {
            return initTopStatistics(missionCenterStatisticsVO);
        }
        // 派单数
        int abnormalDispatchCount = 0;
        int completedDispatchCount = 0;
        int unfinishedDispatchCount = 0;
        int receiveEmpCount = 0;
        // 派单人数
        int abnormalEmpCount = 0;
        int completedEmpCount = 0;
        int unfinishedEmpCount = 0;
        for (MissionCenterListVO missionCenter : resultList) {
            // 如果派单类型是上传图片则不计入统计
            if(missionCenter.getFileType() == 2){
                continue;
            }
            receiveEmpCount += missionCenter.getDispatchEmpCount();
            abnormalEmpCount += missionCenter.getAbnormalCount();
            completedEmpCount += missionCenter.getCompletedCount();
            unfinishedEmpCount += missionCenter.getUnfinishedCount();
            if (missionCenter.getAbnormalCount() > 0) {
                abnormalDispatchCount += 1;
            }
            if (missionCenter.getUnfinishedCount() > 0) {
                unfinishedDispatchCount += 1;
            }
            if (missionCenter.getCompletedCount().equals(missionCenter.getDispatchEmpCount())) {
                completedDispatchCount += 1;
            }
        }
        // 异常人数
        missionCenterStatisticsVO.setAbnormalCount(abnormalEmpCount);
        // 未完成人数
        missionCenterStatisticsVO.setUnfinishedCount(unfinishedEmpCount);
        // 已完成人数
        missionCenterStatisticsVO.setCompletedCount(completedEmpCount);
        // 异常派单数
        missionCenterStatisticsVO.setAbnormalDispatchCount(abnormalDispatchCount);
        // 成功派单数
        missionCenterStatisticsVO.setCompletedDispatchCount(completedDispatchCount);
        // 未完成派单数
        missionCenterStatisticsVO.setUnfinishedDispatchCount(unfinishedDispatchCount);
        // 总接单人数
        missionCenterStatisticsVO.setReceiveEmpCount(receiveEmpCount);
        // 合计接单次数
        missionCenterStatisticsVO.setReceiveCount(resultList.size());
        return missionCenterStatisticsVO;
    }

    @Override
    public Page<MissionCenterListVO> viewMission(MissionCenterQuery missionCenterQuery, TokenUser tokenUser) {
        List<MissionCenterListVO> resultList = viewMissionList(missionCenterQuery, tokenUser);
        if (!ObjectUtils.isEmpty(missionCenterQuery.getMissionCenterState())) {
            resultList = resultList.stream().filter(missionCenter -> {
                List<MissionCenterItemDO> itemList = missionCenterItemService
                        .selectByMissionCenterId(missionCenter.getId(), tokenUser.getSiteId());
                if (!CollectionUtils.isEmpty(itemList)) {
                    List<Integer> itemStateList = itemList.stream()
                            .map(MissionCenterItemDO::getState).collect(Collectors.toList());
                    if (1 == missionCenterQuery.getMissionCenterState()) {
                        return !itemStateList.contains(0) && !itemStateList.contains(2);
                    } else {
                        return itemStateList.contains(missionCenterQuery.getMissionCenterState());
                    }
                } else {
                    return false;
                }
            }).collect(Collectors.toList());
        }
        Page<MissionCenterListVO> resultPage = PageKit.startPage(resultList, missionCenterQuery.getPageNo(), missionCenterQuery.getPageSize());
        List<MissionCenterListVO> resultPageList = resultPage.getEntities();
        // 判断当前用户这些单是否已经接了
        if (!CollectionUtils.isEmpty(resultPageList)) {
            for (MissionCenterListVO missionCenterListVO : resultPageList) {
                String receiveJson = missionCenterListVO.getReceiveJson();
                if (StringUtils.isEmpty(receiveJson)) {
                    missionCenterListVO.setCurrentUserReceive(false);
                } else {
                    missionCenterListVO.setCurrentUserReceive(receiveJson.contains(tokenUser.getUserId()));
                }
            }
            resultPage.setEntities(resultPageList);
        }
        return resultPage;
    }

    @Override
    public Boolean confirmReceive(String missionCenterId, TokenUser tokenUser) {
        MissionCenterDO missionCenterDO = selectDOById(missionCenterId, tokenUser.getSiteId());
        String receiveJson = missionCenterDO.getReceiveJson();
        JSONObject jsonObject;
        if (StringUtils.isEmpty(receiveJson)) {
            jsonObject = new JSONObject();
        } else {
            if (receiveJson.contains(tokenUser.getUserId())) {
                throw new ParamException("您已确认接单,请勿重复操作");
            }
            jsonObject = JSONObject.parseObject(receiveJson);
        }
        jsonObject.put(tokenUser.getUserId(), DateKit8.format2DateTime(new Date()));
        missionCenterDO.setReceiveJson(jsonObject.toJSONString());
        missionCenterDO.setState(1);
        return missionCenterDAO.updateByPrimaryKeySelective(missionCenterDO) == 1;
    }

    @Override
    public String exportWrongsDataPath(MissionCenterExportWrongDTO exportWrongDTO, TokenUser tokenUser) {
        ParamException.notEmpty(exportWrongDTO.getHead(), "Excel表头为空");
        ParamException.notEmpty(exportWrongDTO.getHeadDate(), "Excel数据为空");
        // 表头容器定义
        List<List<String>> headList = new ArrayList<>();
        // 所有的数据容器定义
        List<List<String>> dataList = new ArrayList<>();
        for (String head : exportWrongDTO.getHead()) {
            List<String> oneHead = new ArrayList<>();
            oneHead.add(head);
            headList.add(oneHead);
        }
        List<String> headData = exportWrongDTO.getHeadDate();
        for (String headDataJson : headData) {
            List<String> oneData = new ArrayList<>();
            Map<String, Object> dataMap = JSONObject.parseObject(headDataJson);
            for (String head : exportWrongDTO.getHead()) {
                String data = (String) dataMap.get(head);
                oneData.add(data);
            }
            dataList.add(oneData);
        }
        return ExcelKit.exportExcelDynamic("emptyMissionCenterWrong", "错误数据", dataList, headList);
    }

    @Override
    public List<UserDO> selectAllCreateUserBySite(TokenUser tokenUser) {
        Example example = new Example(MissionCenterDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        List<MissionCenterDO> missionCenterList = missionCenterDAO.selectByExample(example);
        List<String> createUserIdList = missionCenterList.stream()
                .map(MissionCenterDO::getCreateUserId).distinct().collect(Collectors.toList());
        return userProviderService.selectUserByIds(createUserIdList);
    }

    @Override
    public void updateDict(DictItemDO dictItem, DictItemUpdateDTO dictItemUpdateDTO, TokenUser tokenUser) {
        MissionCenterDO missionCenter = new MissionCenterDO();
        Example example = new Example(MissionCenterDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1204".equals(dictItem.getDictCode())) {
            example.and().andEqualTo("missionMode", dictItem.getDictItemValue());
            missionCenter.setMissionMode(dictItemUpdateDTO.getDictItemValue());
            missionCenterDAO.updateByExampleSelective(missionCenter, example);
        }
    }

    @Override
    public Integer selectDict(DictItemDO dictItem, TokenUser tokenUser) {
        Example example = new Example(MissionCenterDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1204".equals(dictItem.getDictCode())) {
            example.and().andEqualTo("missionMode", dictItem.getDictItemValue());
            return missionCenterDAO.selectCountByExample(example);
        } else {
            return 0;
        }
    }

    /**
     * 接单人员查看自己有权限的所有任务
     */
    private List<MissionCenterListVO> viewMissionList(MissionCenterQuery missionCenterQuery, TokenUser tokenUser) {
        Example example = new Example(MissionCenterDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andLike("subjectId", "%" + tokenUser.getUserId() + "%");
        buildExampleDate(missionCenterQuery, example);
        example.orderBy("gmtCreate").desc();
        // 查询派给当前登陆用户的任务
        List<MissionCenterDO> missionCenterListByUser = missionCenterDAO.selectByExample(example);
        // 查询登陆用户拥有的用工单位权限
        List<String> companyIdList = companyService.tileCompanyIdByUser2(tokenUser);
        // 如果没有任何权限则只返回单独派发给当前用户的任务
        if (CollectionUtils.isEmpty(companyIdList)) {
            if (CollectionUtils.isEmpty(missionCenterListByUser)) {
                return new ArrayList<>();
            } else {
                return doToListVo(missionCenterListByUser, tokenUser.getSiteId());
            }
        }
        // 如果拥有当前租户所有用工单位分组权限
        if ("all".equals(companyIdList.get(0))) {
            // 查询当前租户下派发给固定用工单位的任务,查询后和派给当前登录人的任务取并集返回
            List<MissionCenterDO> missionCenterBySiteCompany =
                    selectByCompanyType(missionCenterListByUser, missionCenterQuery, tokenUser);
            if (CollectionUtils.isEmpty(missionCenterBySiteCompany)) {
                return new ArrayList<>();
            } else {
                return doToListVo(missionCenterBySiteCompany, tokenUser.getSiteId());
            }
        } else {
            // 如果没有当前租户所有用工单位分组权限则轮询这个人的所有权限
            List<MissionCenterDO> missionCenterChargeCompany = new ArrayList<>();
            for (String companyId : companyIdList) {
                example.clear();
                example.and()
                        .andEqualTo("valid", true)
                        .andEqualTo("siteId", tokenUser.getSiteId())
                        .andLike("subjectId", "%" + companyId + "%");
                buildExampleDate(missionCenterQuery, example);
                example.orderBy("gmtCreate").desc();
                missionCenterChargeCompany.addAll(missionCenterDAO.selectByExample(example));
            }
            missionCenterChargeCompany.addAll(missionCenterListByUser);
            if (CollectionUtils.isEmpty(missionCenterChargeCompany)) {
                return new ArrayList<>();
            } else {
                return doToListVo(missionCenterChargeCompany, tokenUser.getSiteId());
            }
        }
    }

    /**
     * 查询租户下分配给固定用工单位的任务
     */
    private List<MissionCenterDO> selectByCompanyType(List<MissionCenterDO> missionCenterListByUser,
                                                      MissionCenterQuery missionCenterQuery, TokenUser tokenUser) {
        Example example = new Example(MissionCenterDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("subjectType", FIXED_COMPANY);
        buildExampleDate(missionCenterQuery, example);
        List<MissionCenterDO> missionCenterList = missionCenterDAO.selectByExample(example);
        missionCenterList.addAll(missionCenterListByUser);
        missionCenterList = missionCenterList.stream()
                .sorted(Comparator.comparing(MissionCenterDO::getGmtCreate).reversed())
                .collect(Collectors.toList());
        return missionCenterList;
    }

    /**
     * 把导入的Excel表头和数据数据结构改变一下
     */
    private void parseExcelHead(Map<Integer, String> allHeadMap, List<Map<Integer, String>> parseList, List<String> headList,
                                List<Map<String, String>> headData, Map<Integer, Map<String, String>> wrongsDataMap) {
        // 改变表头数据结构
        for (Integer headIndex : allHeadMap.keySet()) {
            String oneHead = allHeadMap.get(headIndex);
            headList.add(oneHead);
        }
        // 改变数据数据结构
        for (int index = 0; index < parseList.size(); index++) {
            Map<Integer, String> parseListData = parseList.get(index);
            Map<String, String> oneHeadData = new HashMap<>(64);
            for (Integer headIndex : parseListData.keySet()) {
                String head = allHeadMap.get(headIndex);
                oneHeadData.put(head, parseListData.get(headIndex));
            }
            if (wrongsDataMap.containsKey(index)) {
                Map<String, String> wrongsMap = wrongsDataMap.get(index);
                if (wrongsMap.containsKey(NAME_FLAG)) {
                    oneHeadData.put(NAME_WRONGS, wrongsMap.get(NAME_FLAG));
                }
                if (wrongsMap.containsKey(ID_CARD_FLAG)) {
                    oneHeadData.put(ID_CARD_WRONGS, wrongsMap.get(ID_CARD_FLAG));
                }
            }
            headData.add(oneHeadData);
        }
    }


    private List<MissionCenterListVO> fillNumber(List<MissionCenterListVO> resultList, Boolean conversion, String siteId) {
        if (CollectionUtils.isEmpty(resultList)) {
            return resultList;
        }
        // 把createUser先全查出来 变成map
        List<String> createUserIdList = resultList.stream()
                .map(MissionCenterListVO::getCreateUserId).collect(Collectors.toList());
        resultList.stream()
                .map(MissionCenterListVO::getReceiveJson)
                .filter(Objects::nonNull)
                .forEach(receiveJsonStr -> {
                    JSONObject receiveJson = JSONObject.parseObject(receiveJsonStr);
                    createUserIdList.addAll(receiveJson.keySet());
                });
        List<UserDO> userList = userProviderService.selectUserByIds(createUserIdList);
        // <userId, userName>
        Map<String, String> userNameMap = userList.stream().collect(Collectors.toMap(UserDO::getId, UserDO::getName));
        List<String> missionCenterIdList = resultList
                .stream().map(MissionCenterListVO::getId).collect(Collectors.toList());
        List<MissionCenterItemDO> itemList = missionCenterItemService
                .selectByMissionCenterIdList(missionCenterIdList, siteId);
        Map<String, List<MissionCenterItemDO>> itemMap = itemList.stream()
                .collect(Collectors.groupingBy(MissionCenterItemDO::getMissionCenterId));
        for (MissionCenterListVO missionCenterListVO : resultList) {
            if (conversion) {
                String receiveJsonStr = missionCenterListVO.getReceiveJson();
                if (!StringUtils.isEmpty(receiveJsonStr)) {
                    JSONObject jsonObject = new JSONObject();
                    JSONObject receiveJson = JSONObject.parseObject(receiveJsonStr);
                    for (String userId : receiveJson.keySet()) {
                        String userName = userNameMap.get(userId);
                        if (!StringUtils.isEmpty(userName)) {
                            jsonObject.put(userName, receiveJson.get(userId));
                        }
                    }
                    missionCenterListVO.setReceiveJson(jsonObject.toJSONString());
                }
            }
            String userName = userNameMap.get(missionCenterListVO.getCreateUserId());
            if (!StringUtils.isEmpty(userName)) {
                missionCenterListVO.setCreateUser(userName);
            }
            String tableHead = missionCenterListVO.getTableHead();
            if (!StringUtils.isEmpty(tableHead)) {
                String[] headArray = tableHead.split(",");
                List<String> headList = Arrays.asList(headArray);
                // 表头列表
                missionCenterListVO.setHeadList(headList);
            }
            List<MissionCenterItemDO> missionCenterItemList = itemMap.get(missionCenterListVO.getId());
            if (CollectionUtils.isEmpty(missionCenterItemList)) {
                missionCenterListVO.setDispatchEmpCount(0);
                missionCenterListVO.setCompletedCount(0);
                missionCenterListVO.setUnfinishedCount(0);
                missionCenterListVO.setAbnormalCount(0);
            } else {
                Map<Integer, Long> groupByState = missionCenterItemList.stream()
                        .collect(Collectors.groupingBy(MissionCenterItemDO::getState, Collectors.counting()));
                // 总派单人数
                missionCenterListVO.setDispatchEmpCount(missionCenterItemList.size());
                // 已完成人数
                missionCenterListVO.setCompletedCount(null == groupByState.get(1) ? 0 : groupByState.get(1).intValue());
                // 未完成人数
                missionCenterListVO.setUnfinishedCount(null == groupByState.get(0) ? 0 : groupByState.get(0).intValue());
                // 异常人数
                missionCenterListVO.setAbnormalCount(null == groupByState.get(2) ? 0 : groupByState.get(2).intValue());
            }
            missionCenterListVO.setMissionName(missionCenterListVO.getMissionName() +
                    "(" + missionCenterListVO.getMissionMode() + ")");
            // 排序,未完成人数为0说明此单已被完成排序赋值1否则赋值0
            missionCenterListVO.setSort(0 == missionCenterListVO.getUnfinishedCount() ? 1 : 0);
        }
        resultList = resultList.stream()
                .sorted(Comparator.comparing(MissionCenterListVO::getSort))
                .collect(Collectors.toList());
        return resultList;
    }

    /**
     * do 转 ListVo
     */
    private List<MissionCenterListVO> doToListVo(List<MissionCenterDO> missionCenterList, String siteId) {
        List<MissionCenterListVO> result = new ArrayList<>();
        for (MissionCenterDO missionCenterDO : missionCenterList) {
            MissionCenterListVO missionCenterListVO = missionCenterDO.to(MissionCenterListVO.class);
            result.add(missionCenterListVO);
        }
        return fillNumber(result, false, siteId);
    }

    /**
     * 初始化查询派单统计项实体
     */
    private MissionCenterStatisticsVO initTopStatistics(MissionCenterStatisticsVO missionCenterStatisticsVO) {
        missionCenterStatisticsVO.setDispatchEmpCount(0);
        missionCenterStatisticsVO.setCompletedCount(0);
        missionCenterStatisticsVO.setUnfinishedCount(0);
        missionCenterStatisticsVO.setAbnormalCount(0);
        missionCenterStatisticsVO.setDispatchCount(0);
        missionCenterStatisticsVO.setUnfinishedDispatchCount(0);
        missionCenterStatisticsVO.setCompletedDispatchCount(0);
        missionCenterStatisticsVO.setAbnormalDispatchCount(0);
        return missionCenterStatisticsVO;
    }

    /**
     * 构建一个已有的Example根据传入的时间查询参数
     */
    private void buildExampleDate(MissionCenterQuery missionCenterQuery, Example example) {
        if (!StringUtils.isEmpty(missionCenterQuery.getMissionMode())) {
            example.and().andEqualTo("missionMode", missionCenterQuery.getMissionMode());
        }
        if (!StringUtils.isEmpty(missionCenterQuery.getYear()) && !StringUtils.isEmpty(missionCenterQuery.getMonth())) {
            example.and().andEqualTo("year", missionCenterQuery.getYear())
                    .andEqualTo("month", missionCenterQuery.getMonth());
        }
        if (!ObjectUtils.isEmpty(missionCenterQuery.getBeginTime()) &&
                !ObjectUtils.isEmpty(missionCenterQuery.getEndTime())) {
            example.and()
                    .andLessThanOrEqualTo("gmtCreate", missionCenterQuery.getEndTime())
                    .andGreaterThanOrEqualTo("gmtCreate", missionCenterQuery.getBeginTime());
        }
    }

    /**
     * 根据查询参数，构建example
     *
     * @param missionCenterQuery 查询参数
     * @param siteId             所属站点id
     * @return example
     */
    private Example buildExample(MissionCenterQuery missionCenterQuery, String siteId) {
        Example example = new Example(MissionCenterDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (!StringUtils.isEmpty(missionCenterQuery.getMissionMode())) {
            example.and().andEqualTo("missionMode", missionCenterQuery.getMissionMode());
        }
        if (!ObjectUtils.isEmpty(missionCenterQuery.getBeginTime()) &&
                !ObjectUtils.isEmpty(missionCenterQuery.getEndTime())) {
            example.and()
                    .andLessThanOrEqualTo("gmtCreate", missionCenterQuery.getEndTime())
                    .andGreaterThanOrEqualTo("gmtCreate", missionCenterQuery.getBeginTime());
        }
        if (!StringUtils.isEmpty(missionCenterQuery.getYear())) {
            example.and().andEqualTo("year", missionCenterQuery.getYear());
        }
        if (!StringUtils.isEmpty(missionCenterQuery.getMonth())) {
            example.and().andEqualTo("month", missionCenterQuery.getMonth());
        }
        if (!StringUtils.isEmpty(missionCenterQuery.getCreateUserId())) {
            example.and().andEqualTo("createUserId", missionCenterQuery.getCreateUserId());
        }
        // 排序
        ExampleKit.setExampleOrder(example, missionCenterQuery.getOrders());
        return example;
    }
}




